package com.settlement.system.controller;

import com.settlement.system.common.enums.ReturnStatusEnum;
import com.settlement.system.common.enums.WpTypeEnum;
import com.settlement.system.common.exception.ServiceException;
import com.settlement.system.model.entity.common.*;
import com.settlement.system.reply.ObjectDataResponse;
import com.settlement.system.service.*;
import com.settlement.system.common.util.common.CommonAcsUtil;
import com.settlement.system.common.util.common.DictionaryUtil;
import com.settlement.system.common.util.common.FasUtil;
import com.alibaba.excel.context.AnalysisContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * 唯品会账手工差异账单 前端控制器
 * @author Ximi
 * @since 2020-04-17
 */

@Slf4j
@RestController
@RequestMapping("/wp/manualItemDiff")
public class TblWpManualItemDiffController extends ExcelController<TblWpManualItemDiff> {

    @Resource
    private ITblWpManualItemDiffService tblWpManualItemDiffService;

    @Resource
    private DictionaryUtil dictionaryUtil;

    @Resource
    private ICompanyService companyService;

    @Resource
    private CompanyPartConfigService companyPartConfigService;

    @Resource
    private ITblWpItemDiffSourceService iTblWpItemDiffSourceService;

    @Resource
    private ITblWpVendorConfigService tblWpVendorConfigService;

    @Resource
    private ITblWpVendorUncommonShopConfigService tblWpVendorUncommonShopConfigService;

    @Resource
    private ITblWpBrandUnitConfigService tblWpBrandUnitConfigService;

    @Resource
    private IItemService itemService;

    private Map<String,Company> shopCompanyCache =  new ConcurrentHashMap<>();
    private Map<String,CompanyPartConfig> companyPartConfigCache = new ConcurrentHashMap<>();
    private Map<String,TblWpItemDiffSource> diffSourceCache = new ConcurrentHashMap<>();

    @Override
    public IBaseService init() {
        return tblWpManualItemDiffService;
    }

    @Override
    public Class<?> getModelClass() {
        return TblWpManualItemDiff.class;
    }

    @Override
    public String verifyImportObject(TblWpManualItemDiff tblWpManualItemDiff, AnalysisContext analysisContext) {
        String error =  super.verifyImportObject(tblWpManualItemDiff,analysisContext);
        if(!StringUtils.isEmpty(error)){
            return error;
        }
        try {
            List<String> allShopNos = tblWpVendorConfigService.getAllShopNos();
            if(!allShopNos.contains(tblWpManualItemDiff.getShopNo())){
               return "导入的[店铺编码]在【WP-商户配置】中未配置。";
            }

            Company company = getCompany(tblWpManualItemDiff.getShopNo());
            if(company == null){
                return "店铺编码:" + tblWpManualItemDiff.getShopNo() + "无对应的公司";
            }
            tblWpManualItemDiff.setCompanyNo(company.getCompanyNo());
            tblWpManualItemDiff.setCompanyName(company.getName());

            CompanyPartConfig config = getCompanyPartConfig(company.getCompanyNo());
            if(null == config){
                return "店铺编码:" + tblWpManualItemDiff.getShopNo() + "对应的公司无分区设置";
            }
            tblWpManualItemDiff.setShardingFlag(config.getPartitionNo());

            TblWpItemDiffSource itemDiffSource = getItemDiffSource(tblWpManualItemDiff.getBillNumber());
            if(null == itemDiffSource){
                return "账单编码:" + tblWpManualItemDiff.getBillNumber() + "差异明细中不存在";
            }
            tblWpManualItemDiff.setSendDate(itemDiffSource.getSendDate());
            tblWpManualItemDiff.setSettleAccountMonth(itemDiffSource.getSettleAccountMonth());
            tblWpManualItemDiff.setSettleAccountPeriod(itemDiffSource.getSettleAccountPeriod());
            tblWpManualItemDiff.setEntryAccountMonth(itemDiffSource.getEntryAccountMonth());
            tblWpManualItemDiff.setProcessStatus(WpTypeEnum.PROCESS_STATUS.fulling.getNo());
            tblWpManualItemDiff.setOrderType(WpTypeEnum.ORDER_TYPE.DIFF.getNo());
            tblWpManualItemDiff.setBillNumberType(itemDiffSource.getBillNumberType());

            //  确认金额如果为0，那么，100%终端收入=0，100%收入=0，100%平台扣费=0
            //  由于 不允许 100%数量、100%终端收入、100%平台扣费 三个字段都是0，
            //  所以校验 不允许 100%数量、确认金额 同时为0
            if(tblWpManualItemDiff.getAllQty().compareTo(BigDecimal.ZERO)==0
                    && tblWpManualItemDiff.getComfireAmount().compareTo(BigDecimal.ZERO)==0
            ){
               return "不允许 100%数量、确认金额 同时为0";
            }

            String vendorCode = tblWpVendorConfigService.getVendorCodeFromBillNumber(tblWpManualItemDiff.getBillNumber());

            List<TblWpBrandUnitConfig> configList = tblWpBrandUnitConfigService.getBrandUnitConfig(tblWpManualItemDiff.getWpBrandName(),vendorCode);
            if (CollectionUtils.isEmpty(configList)) {
                return "[唯品品牌部名称]"+tblWpManualItemDiff.getWpBrandName()+"+[商家编码]"+vendorCode+" 在【WP-品牌对应配置】中未配置";
            }

            Integer integer = 0;
            for (TblWpBrandUnitConfig wpBrandUnitConfig : configList) {
                integer = tblWpVendorUncommonShopConfigService.
                        selectCountByVdbs(vendorCode, tblWpManualItemDiff.getDeliveryType(), wpBrandUnitConfig.getBrandUnitNo(),tblWpManualItemDiff.getShopNo());
                if(integer==0){
                    integer = tblWpVendorUncommonShopConfigService.
                            selectCountByVdbs(vendorCode, tblWpManualItemDiff.getDeliveryType(), null,tblWpManualItemDiff.getShopNo());
                    if(integer==0){
                        TblWpVendorConfig wpVendorByCode = tblWpVendorConfigService.getWpVendorByCode(vendorCode);
                        if(wpVendorByCode!=null && tblWpManualItemDiff.getShopNo().equals(wpVendorByCode.getShopNo())){
                            integer = 1;
                        }else{
                            integer = 0;
                        }
                    }
                }
                if(integer>0){
                    break;
                }
            }

            if(integer==0){
                return "导入的[店铺编码]在【WP-商户配置】中未配置。";
            }

        } catch (Exception ex){
            log.error(ex.getMessage(),ex);
            return ex.getMessage();
        }
        return error;
    }

    @Override
    @PostMapping("import")
    @CacheEvict(cacheNames = {"getAllShopNos"},allEntries = true, beforeInvocation = true)
    public ObjectDataResponse importFile(MultipartFile file, HttpServletRequest request) {
        return super.importFile(file, request);
    }

    /**
     * 获取公司
     * @param shopNo
     * @return
     * @throws ServiceException
     */
    private Company getCompany(String shopNo) throws ServiceException {
        if(shopCompanyCache.containsKey(shopNo)){
            return shopCompanyCache.get(shopNo);
        }
        Company company = companyService.getCompanyByShopNo(shopNo);
        if(company != null){
            shopCompanyCache.put(shopNo,company);
        }
        return company;
    }

    /**
     * 获取公司分区设置
     * @param companyNo
     * @return
     * @throws ServiceException
     */
    private CompanyPartConfig getCompanyPartConfig(String companyNo) throws ServiceException {
        if(companyPartConfigCache.containsKey(companyNo)){
            return companyPartConfigCache.get(companyNo);
        }
        CompanyPartConfig config = companyPartConfigService.getCompanyPartConfig(companyNo);
        if(null != config){
            companyPartConfigCache.putIfAbsent(companyNo,config);
        }
        return config;
    }

    /**
     * 随机获取一条下载(从唯品平台下载)的差异明细
     * @param billNumber
     * @return
     * @throws ServiceException
     */
    private TblWpItemDiffSource getItemDiffSource(String billNumber) throws ServiceException {
        if(diffSourceCache.containsKey(billNumber)){
            return diffSourceCache.get(billNumber);
        }
        TblWpItemDiffSource itemDiffSource = iTblWpItemDiffSourceService.getRandomItemDiffSource(billNumber);
        if(null != itemDiffSource){
            diffSourceCache.putIfAbsent(billNumber,itemDiffSource);
        }
        return itemDiffSource;
    }


    @Override
    protected void setFootModel(Map<String, Object> result, Map<String, Object> model) throws ServiceException {
        TblWpManualItemDiff foot = tblWpManualItemDiffService.selectFoot(model);
        result.put("foot",foot);
        super.setFootModel(result, model);
    }

    @Override
    protected void setParamsModel(Map<String, Object> model) {
        FasUtil.formatInQueryCondition(model,"shopNo","billNumberType","settleAccountPeriod",
                "brandNo","processStatus","categoryName","billNumber","calendar",
                "globalId","so","poNo","barcode","deliveryType");
        super.setParamsModel(model);
    }

    @Override
    public void saveData(List<TblWpManualItemDiff> datas) throws ServiceException {
        tblWpManualItemDiffService.updateOrSave(datas);
    }


    @Override
    protected ObjectDataResponse batchDelete(@RequestBody List<TblWpManualItemDiff> deleteList, HttpServletRequest request) throws ServiceException {
        try{
            String message = checkDeleteList(deleteList);
            if (StringUtils.isNotEmpty(message)) {
                return new ObjectDataResponse(ReturnStatusEnum.CHECK_FAILURE.getValue(), message);
            }
        } catch (Exception ex) {
            log.info("更新数据异常", ex);
            return new ObjectDataResponse(ReturnStatusEnum.REQUEST_ABNORMAL);
        }
        return super.batchDelete(deleteList, request);
    }

    String checkDeleteList(List<TblWpManualItemDiff> deleteList) throws ServiceException {
        if(CollectionUtils.isEmpty(deleteList)){
            return "未选中任何数据";
        }

        // 允许删除的档期ID的列表： 10154124,10171986,10172658,10172659
        List<String> toBeDeletedScheduleIdList = dictionaryUtil.toBeDeletedScheduleIdList();

        for (TblWpManualItemDiff tblWpBillSaleDetail : deleteList) {
            if(!toBeDeletedScheduleIdList.contains(tblWpBillSaleDetail.getScheduleId())){
                return "非指定档期ID不允许删除";
            }
        }
        List<String> collect = deleteList.stream().map(TblWpManualItemDiff::getId).collect(Collectors.toList());
        List<List<String>> lists = CommonAcsUtil.splitList(collect, 10);

        String scheduleIdInQueryCondition = dictionaryUtil.toBeDeletedScheduleIdInQueryCondition();

        for(List<String> list : lists){
            int i = tblWpManualItemDiffService.selectCountNotYk(list, scheduleIdInQueryCondition);
            if(i>0){
                return "非指定档期ID不允许删除.";
            }
        }

        return null;
    }

}

